package models

import "sort"

type Menu struct {
	ID       int    `json:"id"`
	Name     string `json:"name"`
	Route    string `json:"route"`
	Icon     string `json:"icon"`
	Sort     int    `json:"sort"`
	ParentId int    `json:"parent_id"`
}

type Node struct {
	ID       int    `json:"id"`
	Name     string `json:"name"`
	Route    string `json:"route"`
	Icon     string `json:"icon"`
	Sort     int    `json:"sort"`
	ParentId int    `json:"parent_id"`
	Children []Node `json:"children"`
}

type ByKey []Menu

func (s ByKey) Len() int           { return len(s) }
func (s ByKey) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
func (s ByKey) Less(i, j int) bool { return s[i].Sort < s[j].Sort }

//获取所有菜单
func GetAllMenu() (menus []Menu, err error) {
	err = db.Order("sort asc").Find(&menus).Error

	return
}

//新增菜单
func AddMenu(menu Menu) (err error) {
	err = db.Create(menu).Error

	return
}

//更新菜单
func UpdateMenu(id int, data map[string]interface{}) (err error) {
	err = db.Where("id =?", id).Updates(data).Error

	return
}

//删除菜单
func DelMenu(id int) (err error) {
	err = db.Where("id = ?", id).Delete(Menu{}).Error

	return
}

//判断某个菜单是否有子菜单
func MenuHasChild(pid int) bool {
	var menu Menu
	db.Where("parent_id = ?", pid).First(menu)

	return menu.ID > 0
}

//获取所有父菜单
func GetTopMenu() (menus []Menu, err error) {
	err = db.Where("parent_id = ? AND route = ?", 0, "").Find(&menus).Error

	return
}

//获取所有子菜单
func GetSubmenu() (menus []Menu, err error) {
	err = db.Where("parent_id <> ?", 0).Or("route <> ?", "").Find(&menus).Error

	return
}

//获取单个用户的菜单
func GetMenuByUid(uid interface{}) ([]Menu, error) {
	var (
		user     User
		menus    []Menu
		topMenus []Menu
		pids     []int
	)

	err := db.Preload("Role").First(&user, uid).Error
	if err != nil {
		return menus, err
	}

	//通过关联关系获取用户的菜单
	err = db.Model(user.Role).Association("Menus").Find(&menus)
	//获取菜单的父级ID
	for _, item := range menus {
		if item.ParentId > 0 {
			pids = append(pids, item.ParentId)
		}
	}

	//获取菜单的父级,并且追加到菜单列表中
	if len(pids) > 0 {
		db.Where("id IN ?", pids).Find(&topMenus)
		if len(topMenus) > 0 {
			menus = append(menus, topMenus...)
		}
	}

	//对菜单进行排序
	sort.Sort(ByKey(menus))

	return menus, err
}

//递归生成菜单树形结构
func GenTree(pid int, menus []Menu) []Node {
	nodes := []Node{}
	for _, menu := range menus {
		if menu.ParentId == pid {
			children := GenTree(menu.ID, menus)
			node := Node{
				ID:       menu.ID,
				Name:     menu.Name,
				Route:    menu.Route,
				Icon:     menu.Icon,
				Sort:     menu.Sort,
				ParentId: menu.ParentId,
				Children: children,
			}
			nodes = append(nodes, node)
		}
	}

	return nodes
}
